package com.jfs.envent.listener;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jfs.entity.DeviceChannel;
import com.jfs.envent.entity.DeviceList;
import com.jfs.envent.entity.Info;
import com.jfs.envent.entity.Item;
import com.jfs.envent.entity.MessageDeviceCataLogEntity;
import com.jfs.service.DeviceChannelService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description 设备查询目录信息监听器
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/8/1
 */
@Component
@Slf4j
@AllArgsConstructor
public class DeviceCataLogEventListener implements ApplicationListener<MessageDeviceCataLogEntity> {
    private final DeviceChannelService deviceChannelService;

    /**
     * 防止多线程情况下 设备多次响应 通道主键冲突问题
     */
    private final static ReentrantLock LOCK =new ReentrantLock(true);

    @Override
    @Async
    public void onApplicationEvent(MessageDeviceCataLogEntity event) {
        if (log.isDebugEnabled()) {
            log.info("【设备号:{},设备ip:{},设备端口号:{}】，查询到设备目录信息：{}", event.getDeviceID(), event.getIp(), event.getPort(), JSONUtil.toJsonStr(event));
        }
        try {
            DeviceList deviceList = event.getDeviceList();
            if (Objects.nonNull(deviceList)) {
                Item item = deviceList.getItem();
                if (Objects.nonNull(item)) {
                    LOCK.lock();
                    //1.根据通道id查询通道详情
                    DeviceChannel deviceChannel = deviceChannelService.getOne(Wrappers.<DeviceChannel>lambdaQuery()
                            .eq(DeviceChannel::getChannelId, item.getDeviceID())
                            .eq(DeviceChannel::getDeviceId,event.getDeviceID())
                    );
                    //2.保存或者更新通道信息
                    if (Objects.nonNull(deviceChannel)) {
                        //更新通道信息
                        updateDeviceChannel(event, deviceChannel);
                    } else {
                        //插入
                        insertDeviceChannel(event);
                    }
                }
            }
        } catch (Exception e) {
            log.error("设备目录查询监听器发生异常:{}", e.getMessage());
            e.printStackTrace();
        }finally {
            LOCK.unlock();
        }
    }

    /**
     * 更新通道信息
     *
     * @param entity
     * @param deviceChannel
     */

    public void updateDeviceChannel(MessageDeviceCataLogEntity entity, DeviceChannel deviceChannel) {
        //所属设备id
        deviceChannel.setDeviceId(entity.getDeviceID());
        Item item = entity.getDeviceList().getItem();
        if (Objects.nonNull(item)) {
            //ip
            deviceChannel.setIp(item.getAddress());
            if (StrUtil.isNotEmpty(item.getName())){
                //通道名称
                deviceChannel.setName(item.getName());
            }
            //设备型号
            deviceChannel.setModel(item.getModel());
            //设备制造商
            deviceChannel.setManufacturer(item.getManufacturer());
            //行政区域
            deviceChannel.setCivilCode(item.getCivilCode());
            //纬度
            deviceChannel.setLatitude(StrUtil.isNotEmpty(item.getLatitude()) ? Double.parseDouble(item.getLatitude()) : 0D);
            //经度
            deviceChannel.setLongitude(StrUtil.isNotEmpty(item.getLongitude()) ? Double.parseDouble(item.getLongitude()) : 0D);
            //设备归属
            deviceChannel.setOwner(item.getOwner());
            //是否有子设备1有，0没有
            deviceChannel.setParental(item.getParental());
            //保密属性缺省为0；0：不涉密，1：涉密
            deviceChannel.setSecrecy(Integer.parseInt(item.getSecrecy()));
            //注册方式缺省为1； 1： 符合IETF RFC 3261标准的认证注册模式；2： 基于口令的双向认证注册模式；3： 基于数字证书的双向认证注册模式
            deviceChannel.setRegisterWay(Integer.parseInt(item.getRegisterWay()));
            //信令安全模式（缺省为0；  0：不采用；2：S/MIME签名方式；3：S/MIME加密签名同时采用方式；4：数字摘要方式
            deviceChannel.setSafetyWay(item.getSafetyWay());
            //在线状态0离线1在线
            deviceChannel.setStatus(item.getStatus().equals("ON") ? Boolean.TRUE : Boolean.FALSE);
            Info info = item.getInfo();
            if (Objects.nonNull(info)) {
                //摄像机类型扩展，标识摄像机类型：1-球机；2-半球；3-固定枪机；4-遥控枪机。当目录项为摄像机时可选
                deviceChannel.setPtzType(Integer.parseInt(info.getPtzType()));
            }
        }
        this.deviceChannelService.update(deviceChannel, Wrappers.<DeviceChannel>lambdaUpdate().eq(DeviceChannel::getChannelId, deviceChannel.getChannelId()));
    }

    /**
     * 添加通道信息
     *
     * @param entity
     */
    public void insertDeviceChannel(MessageDeviceCataLogEntity entity) {
        DeviceChannel deviceChannel = new DeviceChannel();
        //所属设备id
        deviceChannel.setDeviceId(entity.getDeviceID());
        Item item = entity.getDeviceList().getItem();
        if (Objects.nonNull(item)) {
            //设置通道Id
            deviceChannel.setChannelId(item.getDeviceID());
            //ip
            deviceChannel.setIp(item.getAddress());
            //通道名称
            deviceChannel.setName(item.getName());
            //设备型号
            deviceChannel.setModel(item.getModel());
            //设备制造商
            deviceChannel.setManufacturer(item.getManufacturer());
            //行政区域
            deviceChannel.setCivilCode(item.getCivilCode());
            //纬度
            deviceChannel.setLatitude(StrUtil.isNotEmpty(item.getLatitude()) ? Double.parseDouble(item.getLatitude()) : 0D);
            //经度
            deviceChannel.setLongitude(StrUtil.isNotEmpty(item.getLongitude()) ? Double.parseDouble(item.getLongitude()) : 0D);
            //设备归属
            deviceChannel.setOwner(item.getOwner());
            //是否有子设备1有，0没有
            deviceChannel.setParental(item.getParental());
            //保密属性缺省为0；0：不涉密，1：涉密
            deviceChannel.setSecrecy(Integer.parseInt(item.getSecrecy()));
            //注册方式缺省为1； 1： 符合IETF RFC 3261标准的认证注册模式；2： 基于口令的双向认证注册模式；3： 基于数字证书的双向认证注册模式
            deviceChannel.setRegisterWay(Integer.parseInt(item.getRegisterWay()));
            //信令安全模式（缺省为0；  0：不采用；2：S/MIME签名方式；3：S/MIME加密签名同时采用方式；4：数字摘要方式
            deviceChannel.setSafetyWay(item.getSafetyWay());
            //在线状态0离线1在线
            deviceChannel.setStatus(item.getStatus().equals("ON") ? Boolean.TRUE : Boolean.FALSE);
            Info info = item.getInfo();
            if (Objects.nonNull(info)) {
                //摄像机类型扩展，标识摄像机类型：1-球机；2-半球；3-固定枪机；4-遥控枪机。当目录项为摄像机时可选
                deviceChannel.setPtzType(Integer.parseInt(info.getPtzType()));
            }
            this.deviceChannelService.save(deviceChannel);
        }
    }
}
